package com.util.wx;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.util.Base64;
import com.util.Config;
import com.util.StringUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

//获取到全局access_token
public class WXUtils {
    public static String APP_ID = "";
    public static String SECRET = "";

    //获取基础access_token,用于验证调用其他微信接口，每天限制2000次，每次token有效期为2小时
    public static final String GET_BASE_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    //获取微信JS-SDK接口使用凭证，每次申请的凭证有效期为2小时
    public static final String GET_JSAPT_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
    //获取网页授权access_token,用于验证跳转的其他网页访问权限，无限制
    public static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";
    //多媒体文件下载
    public static final String GET_MEDIA_DOW_URL = "http://file.api.weixin.qq.com/cgi-bin/media/get";

    public static String access_token = "";

    //存放微信全局票据
    private static Map<String, Map<String, Object>> wx_global_cache = new Hashtable<String, Map<String, Object>>();
    private static final long WX_TIMEOUT = 300;//凭证过去时间 ，单位秒,官方有效期为7200，提前5分钟刷新凭证

    static {
        //从config.properties配置文件读取微信信息
        APP_ID = Config.getString("wx.appid");
        SECRET = Config.getString("wx.appsecret");
    }

    //获取基础验证token
    public static String getBaseToken() {
        boolean isRefreshToken = false;
        String token = "";
        if (wx_global_cache.containsKey("base_token")) {
            Map<String, Object> basetokenmap = wx_global_cache.get("base_token");
            Long lasttime = (Long) basetokenmap.get("expires_outtime");//到期时间
            Long nowtime = System.currentTimeMillis() / 1000;
            if ((lasttime - nowtime) <= WX_TIMEOUT) {
                isRefreshToken = true;
            } else {
                token = (String) basetokenmap.get("token");
            }
        } else {
            isRefreshToken = true;
        }
        //刷新凭证
        if (isRefreshToken) {
            String turl = String.format("%s?grant_type=client_credential&appid=%s&secret=%s", GET_BASE_TOKEN_URL, APP_ID, SECRET);
            reqWxService(turl);//请求微信服务获取验证参数
            if (json.get("statusCode").getAsInt() == HttpStatus.SC_OK) {
                if (json.get("errcode") != null) {
                    // 错误时微信会返回错误码等信息，{"errcode":40013,"errmsg":"invalid appid"}
                } else {
                    Map<String, Object> map = new HashMap<String, Object>();
                    token = json.get("access_token").getAsString();
                    map.put("token", token);
                    map.put("expires_outtime", System.currentTimeMillis() / 1000 + json.get("expires_in").getAsLong());
                    wx_global_cache.put("base_token", map);
                }
            }
        }
        return token;
    }

    //获取微信JS-SDK接口使用凭证
    public static String getJSApiTicket() {
        boolean isRefreshTicket = false;
        String ticket = "";
        if (wx_global_cache.containsKey("jsapi_ticket")) {
            Map<String, Object> ticketmap = wx_global_cache.get("jsapi_ticket");
            Long lasttime = (Long) ticketmap.get("expires_outtime");
            Long nowtime = System.currentTimeMillis() / 1000;
            if ((lasttime - nowtime) <= WX_TIMEOUT) {
                isRefreshTicket = true;
            } else {
                ticket = (String) ticketmap.get("ticket");
            }
        } else {
            isRefreshTicket = true;
        }
        //刷新凭证
        if (isRefreshTicket) {
            String turl = String.format("%s?access_token=%s&type=jsapi", GET_JSAPT_TICKET_URL, getBaseToken());
            reqWxService(turl);//请求微信服务获取验证参数
            if (json.get("statusCode").getAsInt() == HttpStatus.SC_OK) {
                if (json.get("errcode").getAsInt() == 0) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    ticket = json.get("ticket").getAsString();
                    map.put("ticket", ticket);
                    map.put("expires_outtime", System.currentTimeMillis() / 1000 + json.get("expires_in").getAsLong());
                    wx_global_cache.put("jsapi_ticket", map);
                }
            }
        }
        return ticket;
    }

    /**
     * 获取微信JSAPI调用签名
     *
     * @param url 页面url
     * @return
     */
    public static Wx_JsApi_Sign getSign(String url) {
        String jsapi_ticket = getJSApiTicket();
        return Wx_Sign.getSign(jsapi_ticket, url);
    }

    // 获取网页授权token
    public static String getToken(String code) {
        return getToken(GET_ACCESS_TOKEN_URL, APP_ID, SECRET, code);
    }

    public static String getToken(String apiurl, String appid, String secret, String code) {
        String turl = String.format("%s?appid=%s&secret=%s&code=%s&grant_type=authorization_code", apiurl, appid, secret, code);
        System.out.println(code);

        String result = null;
        reqWxService(turl);//请求微信服务获取验证参数
        if (json.get("statusCode").getAsInt() == HttpStatus.SC_OK) {
            if (json.get("errcode") != null) {
                // 错误时微信会返回错误码等信息，{"errcode":40013,"errmsg":"invalid appid"}
            } else {
                // 正常情况下{"access_token":"ACCESS_TOKEN","expires_in":7200}
                result = json.get("openid").getAsString();
                access_token = json.get("access_token").getAsString();
            }
        }
        return result;
    }

    /**
     * 下载图片文件
     *
     * @param mediaId 微信服务器上存放图片的ID
     */
    public static String getMedia_ImgStr(String mediaId) {
        String turl = String.format("%s?access_token=%s&media_id=%s", GET_MEDIA_DOW_URL, getBaseToken(), mediaId);

        InputStream in = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(turl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            //			String imgtype = connection.getContentType();
            in = connection.getInputStream();
            byte[] zp = Base64.inputTobyte(in);
            in.close();
            return Base64.encode(zp);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (connection != null) connection.disconnect();
        }
        return null;
    }

    public static byte[] getMedia_ImgByte(String mediaId) {
        String turl = String.format("%s?access_token=%s&media_id=%s", GET_MEDIA_DOW_URL, getBaseToken(), mediaId);

        InputStream in = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(turl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            in = connection.getInputStream();
            byte[] zp = Base64.inputTobyte(in);
            in.close();
            return zp;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (connection != null) connection.disconnect();
        }
        return null;
    }


    private static JsonParser jsonparer = new JsonParser();// 初始化解析json格式的对象
    private static JsonObject json = null;

    /**
     * 请求微信服务
     *
     * @return JSON
     */
    private static void reqWxService(String url) {
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(url);
        try {
            HttpResponse res = client.execute(get);
            String responseContent = null; // 响应内容
            HttpEntity entity = res.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
            json = jsonparer.parse(responseContent).getAsJsonObject();
            json.addProperty("statusCode", res.getStatusLine().getStatusCode());
            json.addProperty("statusMsg", res.getStatusLine().getReasonPhrase());
            System.out.println(json.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接 ,释放资源
            client.getConnectionManager().shutdown();
        }
    }

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }

}
